package com.css.sword.knowing.search.test;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.elasticsearch.ElasticsearchException;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentFactory;
import org.elasticsearch.search.aggregations.bucket.terms.Terms;
import org.elasticsearch.search.aggregations.bucket.terms.Terms.Bucket;

import com.css.sword.knowing.search.HighLightField;
import com.css.sword.knowing.search.OrderField;
import com.css.sword.knowing.search.SearchField;
import com.css.sword.knowing.search.SearchInput;
import com.css.sword.knowing.search.SearchResult;
import com.css.sword.knowing.search.Searcher;
import com.css.sword.knowing.search.aggregation.AggBucket;
import com.css.sword.knowing.search.aggregation.AggInput;
import com.css.sword.knowing.search.aggregation.AggMetrics;
import com.css.sword.knowing.search.aggregation.AggResult;
import com.css.sword.knowing.search.aggregation.BucketResult;
import com.css.sword.knowing.search.aggregation.MetricsResult;
import com.css.sword.knowing.search.aggregation.SearchAndAggResult;
import com.css.sword.knowing.search.comm.SearchConst;
import com.css.sword.knowing.search.exception.ArgException;

public class searchNews {

	private static final String IDFieldName = null;
	private static final ArrayList AggBucket = null;
	private String indexname = "";
	private String[] typename = {};

	private String keyword = "";
	private String srcname = "";
	private int pagesize = 10;
	private int pageno = 1;
	private int year = 0;
	private int month = 0;

	public String getIndexname() {
		return (indexname);
	}

	public void setIndexname(String indexname) {
		this.indexname = indexname;
	}
	
	public String[] getTypename() {
		return (typename);
	}
	
	public void setTypename(String[] typename) {
		this.typename = typename;
	}

	public String getKeyword() {
		return (keyword);
	}

	public void setKeyword(String keyword) {
		this.keyword = keyword;
	}

	public String getSrcname() {
		return (srcname);
	}

	public void setSrcname(String srcname) {
		this.srcname = srcname;
	}

	public int getPagesize() {
		return (pagesize);
	}

	public void setPagesize(int pagesize) {
		this.pagesize = pagesize;
	}

	public int getPageno() {
		return (pageno);
	}

	public void setPageno(int pageno) {
		this.pageno = pageno;
	}

	public int getYear() {
		return (year);
	}

	public void setYear(int year) {
		this.year = year;
	}

	public int getMonth() {
		return (month);
	}

	public void setMonth(int month) {
		this.month = month;
	}

	public AggBucket setFacetField(String fname, int size)
	{
		AggBucket ab = new AggBucket();
		
		ab.setAggName(fname);
		ab.setField(fname);
		ab.setSize(size);
		ab.setType(SearchConst.AGG_TYPE_TERMS);
		
		return ab;
	}
	public String indexSearch(String name) throws IOException, ElasticsearchException, ArgException                                                                                                      
	{
		String jsonString = "";

		SearchInput si = new SearchInput();                                                                                                                                                                              
	//	si.setIndexName(indexname);                                                                                                                                                                                
	//	si.setTypeNames(typename);
	
		AggInput ai = new AggInput();
		List<AggBucket> abs = new ArrayList();
		ai.setAggBuckets(abs);
		ai.setIndexName(indexname);
		ai.setTypeNames(typename);
		
		ai.setSi(si);
		
		SearchField sf1 = new SearchField();                                                                                                                                                                      
		sf1.setField("content");                                                                                                                                                                                    
		sf1.setOperator(SearchConst.SEARCH_OPERATOR_SHOULD);                                                                                                                                                                
		sf1.setSearchValue(keyword);   

		SearchField sf2 = new SearchField();                                                                                                                                                                      
		sf2.setField("title");                                                                                                                                                                                    
		sf2.setOperator(SearchConst.SEARCH_OPERATOR_SHOULD);                                                                                                                                                                
		sf2.setSearchValue(keyword); 

		
		SearchField[] children = new SearchField[2];                                                                                                                                                                     
		children[0] = sf1;                                                                                                                                                              
		children[1] = sf2;  

		SearchField sf12 = new SearchField();
		sf12.setChildrenField(children);
		sf12.setOperator(SearchConst.SEARCH_OPERATOR_MUST);

		ArrayList<SearchField> where = new ArrayList<SearchField>();
		where.add(sf12);

		if(year > 0)
		{
			SearchField f = new SearchField();                                                                                                                                                                      
			f.setField("year"); 
			f.setValueType(SearchConst.SEARCH_VALUE_TYPE_INT);
			f.setOperator(SearchConst.SEARCH_OPERATOR_MUST);                                                                                                                                                                
			f.setSearchValue(String.valueOf(year));
			where.add(f);
		}

		if(month > 0)
		{
			SearchField f = new SearchField();                                                                                                                                                                      
			f.setField("month");                   
			f.setValueType(SearchConst.SEARCH_VALUE_TYPE_INT);                                                                                                                                       
			f.setOperator(SearchConst.SEARCH_OPERATOR_MUST);                                                                                                                                                                
			f.setSearchValue(String.valueOf(month));
			where.add(f);
			
		}

		if(!srcname.isEmpty())
		{
			SearchField f = new SearchField();                                                                                                                                                                      
			f.setField("srcname");                                                                                                                                                          
			f.setOperator(SearchConst.SEARCH_OPERATOR_MUST);                                                                                                                                                                
			f.setSearchValue(srcname);
			where.add(f);
		}

		si.setSearchFields(where);
		si.setReturnFields(new String[]{"hkey", "title", "urlname", "sitename", "pagetime", "content"});       
/*		
//字段 name 和 introducation命中关键词高亮
		HighLightField[] hlfs = new HighLightField[2];                                                                                                                                                                   

		HighLightField hlf = new HighLightField();
		hlf.setFieldName("title");                                                                                                                                                                   
		hlf.setHighlighterPreTags("<b>");                                                                                                                                                                                
		hlf.setHighlighterPostTags("</b>");
		
		HighLightField hlf1 = new HighLightField();
		hlf1.setFieldName("content");                                                                                                                                                                   
		hlf1.setHighlighterPreTags("<b>");                                                                                                                                                                                
		hlf1.setHighlighterPostTags("</b>");
		
		hlfs[0] = hlf;
		hlfs[1] = hlf1;
				
		si.setHighLightFields(hlfs);                                                                                                                                                                                     
*/		           

		OrderField sort = new OrderField();
		sort.setFieldName("pagetime");
		sort.setOrder(SearchConst.SEARCH_ORDER_TYPE_DESC);
		si.setOrderFields(new OrderField[]{sort});
		
		si.setSystemID(SearchConst.PUBLIC_PRIV);                                                                                                                                                                                        
		si.setFrom((pageno-1) * pagesize);                                                                                                                                                                                                   
		si.setSize(pagesize);
	
		if(srcname.isEmpty())
			abs.add(setFacetField("srcname", 10));
        
		if(year > 0)
		{
			if(month <= 0)
				abs.add(setFacetField("month", 10));
		}
		else 
		{
			abs.add(setFacetField("year", 10));
		}
	
		SearchAndAggResult saar = Searcher.makeAggregation(ai);

		
//		AggResult ar =saar.getAggResult();		
//		getAggResult(ar);	
		
		String[] associate = new String[0];//CssKM.km_associate(name, keyword, 10, false);
		
		jsonString = rss2Json(saar.getSearchResults(), saar.getAggResult(), associate);
		
		return jsonString;                                                                                                                                                                                 
	}
	
	public String rss2Json(List<SearchResult> rss, AggResult ar, String[] associate) throws IOException
	{
		XContentBuilder jsonBuilder = XContentFactory.jsonBuilder();
		
		for(SearchResult rs : rss)                                                                                                                                                                                      
		{		
			long count = rs.getTotalNum();
			long pagenum = (long) Math.ceil((double)count/pagesize);
			
			jsonBuilder.startObject();     
			
			jsonBuilder.field("count", rs.getTotalNum());
	        jsonBuilder.field("total", rs.getTotalNum());
	        jsonBuilder.field("pagenum", pagenum);
			                  
			jsonBuilder.startArray("docs");
            List<Map> data = rs.getData();                                                                                                                                                                                           
			String key=null;                                                                                                                                                                                             
			Object value = null;                                                                                                                                                                                         
			for(Map<String,String> fields : data)                                                                                                                                                                        
			{          
				jsonBuilder.startObject();
				Iterator<String> it = fields.keySet().iterator();                                                                                                                                                        
				while(it.hasNext())                                                                                                                                                                                      
				{					
					key = it.next();                                                                                                                                                                                     
					value = fields.get(key);                                                                                                                                                                             
			         
					if("_id".equalsIgnoreCase(key))
						continue;
					
					if("content".equalsIgnoreCase(key))
					{
						key = "summary";
//						value = CssKM.km_summary(keyword, "", value.toString(), "<font color=\"red\">", "</font>", 300, false);
					}
					if("title".equalsIgnoreCase(key))
					{
//						value = CssKM.km_hits(keyword, value.toString(), "<font color=\"red\">", "</font>", false);
					}
					jsonBuilder.field(key, value);                                                                                                                                              
				}                                                                                                                                                                                                        
				jsonBuilder.endObject();                                                                                                                                                                                   
			}
			jsonBuilder.endArray();
			
			break;
		}   
		
		jsonBuilder.startObject("facet");

		Map<String, List<BucketResult>> bMap = ar.getBucketResultMap();
		if(null!=bMap)
		{
			for(String aggName:bMap.keySet())
			{
				List<BucketResult> bucketResults = bMap.get(aggName);
				jsonBuilder.startArray(aggName);
				
				for(BucketResult br: bucketResults)
				{
					Map<String, AggResult> aggResultMap =  br.getBucketAgg();
					
	    	    	
					if(null==aggResultMap)
						continue;

					
					Iterator<Map.Entry<String, AggResult>> entries = aggResultMap.entrySet().iterator();  
					  
					if(entries.hasNext()) {  
					  
					    Map.Entry<String, AggResult> entry = entries.next();
					    
					    if(("month".equals(aggName) || "year".equals(aggName)) &&  "0".equals(entry.getKey()))
					    		continue;
					    
						jsonBuilder.startObject();
					    jsonBuilder.field("name", entry.getKey());
						jsonBuilder.field("count", br.getDocNumber());
		    	    	jsonBuilder.field("total", br.getDocNumber());
		    			jsonBuilder.endObject();
					}
				}
	            jsonBuilder.endArray();
			} 
		}
		jsonBuilder.endObject();
		
		if(associate!=null && associate.length>0)
		{
			jsonBuilder.array("terms", associate);
		}
		else
		{
			jsonBuilder.startArray("terms");
            jsonBuilder.endArray();
		}
        
		jsonBuilder.endObject();  

        String jsonString = jsonBuilder.string();
        
		return jsonString;
	}
	
	public String getSearch(String name) throws IOException, ElasticsearchException, ArgException{
		
		XContentBuilder jsonBuilder = XContentFactory.jsonBuilder();
		
		return indexSearch(name);
	}
	
	
    private static void getAggResult(AggResult ar) {
		
		List<MetricsResult> l = ar.getMetricsResults();
		if(null!=l)
		{
			getMetricsResult(l);
		}

		Map<String, List<BucketResult>> bMap = ar.getBucketResultMap();
		if(null!=bMap)
		{
			for(String aggName:bMap.keySet())
			{
				List<BucketResult> bucketResults = bMap.get(aggName);
				System.out.println(aggName);
				for(BucketResult br: bucketResults)
				{
					Map<String, AggResult> aggResultMap =  br.getBucketAgg();
					System.out.println("docNumber:" + br.getDocNumber());
					if(null!=aggResultMap)
					{
						for(String bucketKey : aggResultMap.keySet())
						{
							System.out.println("   " + bucketKey);
							getAggResult(aggResultMap.get(bucketKey));
							
						}
					}
					
				}
			}
		}
	}

	private static void getMetricsResult(List<MetricsResult> l) {
		
		for(MetricsResult mr : l)
		{
			System.out.println(mr.getAggName());
			List<Map<String, Number>> metricsList = mr.getMetrics();
			for(Map<String, Number> map : metricsList)
			{
				if(map!=null)
				{
					for(String metricsKey : map.keySet())
					{
						System.out.print(metricsKey + ":");
						System.out.println(map.get(metricsKey));
					}
				}
			}
		}
	}

	private static boolean isChinese(char c)
	{
		Character.UnicodeBlock ub = Character.UnicodeBlock.of(c);
		if (ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS
				|| ub == Character.UnicodeBlock.CJK_COMPATIBILITY_IDEOGRAPHS
				|| ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A
				|| ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_B
				|| ub == Character.UnicodeBlock.CJK_SYMBOLS_AND_PUNCTUATION
				|| ub == Character.UnicodeBlock.HALFWIDTH_AND_FULLWIDTH_FORMS
				|| ub == Character.UnicodeBlock.GENERAL_PUNCTUATION) {
			return true;
		}
		return false;
	}

	public static String[] getSuggest(String name, String key, int count, boolean wt) {
		String[] spells = null;
		ArrayList<String> ret = new ArrayList<String>();
//		String str = "";
//		String cStr = "";
//		boolean flag = true;
//
//		for (int index = 0; index < key.length(); index++) {
//			char ch = key.charAt(index);
//
//			if (isChinese(ch)) {
//				spells = CssKM.km_spell(String.valueOf(ch));
//				if (spells != null && spells.length > 0)
//					str += spells[0];
//				if(flag)
//					cStr += ch;
//			} else {
//				flag = false;
//				str += ch;
//			}
//		}
//
//		String[] words = CssKM.km_suggest(name, str, count*10, wt);
//		if(words != null)
//		{
//			for(int i=0; i<words.length; i++)
//	    	{				
//	    		if(words[i].indexOf(cStr)==0)
//	    			ret.add(words[i]);
//	    		if(ret.size() >= count)
//	    			break;
//	    	}
//		}
		return ret.toArray(new String[ret.size()]);
	}
	
	public static void main(String[] args) throws IOException, ElasticsearchException, ArgException{

//		String[] ret = getSuggest("news", "新",  10, false);
//		System.out.println(Arrays.asList(ret));
//		
		searchNews s = new searchNews();
		
		s.setIndexname("artistnews");
		s.setTypename(new String[]{});
		s.setKeyword("新闻");
	//	s.setMonth(10);
	//	s.setYear(2015);
	//	s.setSrcname("北京日报");
		s.setPagesize(10);
		s.setPageno(1);
		
		
		String ret = s.getSearch("news");

		System.out.println("++++++++++++++++++json++++++++++++++++++++");
		System.out.println(ret);
		
//		s.agg();
		
	//	Searcher.terms("artistnews", "news");
		//Searcher.b();
	}
}

